package day1104;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.*;

/**
 * @author Mr.ma
 * @since 2022/11/4 15:08
 * 方法引用简介：lambda表达式的另一种表现方式，在满足某些条件的情况下使用，更为简洁
 * 方法引用条件：当lambda表达式右侧方法体中只有一条语句，
 *             且该语句是为了调用一个已存在的方法时，则初步满足方法引用使用的条件，
 *             进一步的条件则是对参数进行限制，
 *             要求函数式接口的参数同样要是调用的方法所需要的参数
 * 方法引用的分类：
 *      静态方法引用：类名::静态方法名，相当于(arg0)->类名.静态方法名(arg0)
 *      实例方法引用：对象名::实例方法名，相当于(arg0)->对象名.实例名(arg0)
 *      对象方法引用：类名::实例方法名，相当于(arg0,arg1)->arg0.实例方法名(arg1)
 *      构造方法引用：类名/数组类型::new，相当于(arg0)->new 类名(arg0)
 **/
public class TestMethods {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);list.add(9);list.add(5);list.add(4);list.add(2);list.add(8);list.add(7);
        // 对象方法引用
        Collections.sort(list, Integer::compareTo);
        // 构造器方法引用
        Cat cat01 = makeCat(Cat::new,"老六",13);
        System.out.println("cat01 = " + cat01);
        // 实例方法引用
        System.out.println(getCatInfo(cat01::getAge));
        Function<Cat,Object> function = (x)->x.getName();
        Function<Cat,Object> function2 = Cat::getName;
        System.out.println(function2.apply(cat01));
        Function<String,String> function1 = String::toUpperCase;
        System.out.println(function1.apply("abc"));
        // 静态方法引用
        arrMethod(new int[]{1,2,3,4,5,6},TestMethods::sum);
        arrMethod(new int[]{1,2,3,4,5,6},TestMethods::multi);
    }
    public static void sum(int[] arr){
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        System.out.println("sum = " + sum);
    }
    public static void multi(int[] arr){
        int multi = 1;
        for (int i = 0; i < arr.length; i++) {
            multi *= arr[i];
        }
        System.out.println("multi = " + multi);
    }
    public static void arrMethod(int[] arr, Consumer<int[]> consumer){
        consumer.accept(arr);
    }
    public static Cat makeCat(BiFunction<String,Integer,Cat> biFunction, String name, Integer age){
        return biFunction.apply(name, age);
    }
    public static Object getCatInfo(Supplier<Object> supplier){
        return supplier.get();
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Cat {
    private String name;
    private int age;
}
